package com.kedll.library.util;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.Color;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Environment;
import android.provider.Settings.Secure;
import android.support.annotation.NonNull;
import android.support.design.widget.TabLayout;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.view.ViewPager;
import android.telephony.TelephonyManager;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.ForegroundColorSpan;
import android.text.style.LeadingMarginSpan;
import android.text.style.RelativeSizeSpan;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.flexbox.AlignItems;
import com.google.android.flexbox.FlexDirection;
import com.google.android.flexbox.FlexWrap;
import com.google.android.flexbox.FlexboxLayoutManager;
import com.google.android.flexbox.JustifyContent;
import com.kedll.library.KBaseApplication;
import com.kedll.library.adapter.TabLayoutFragmentPagerAdapter;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.security.MessageDigest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.Random;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.InflaterOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import io.reactivex.disposables.Disposable;


public class MyUtils {
    private final static String SLAT = "zhaipinzhiying";    //add shibo.zheng 19/06/27
    private final static String[][] MIME_MapTable = {
            // {后缀名， MIME类型}
            {".3gp", "video/3gpp"},
            {".apk", "application/vnd.android.package-archive"},
            {".asf", "video/x-ms-asf"},
            {".avi", "video/x-msvideo"},
            {".bin", "application/octet-stream"},
            {".bmp", "image/bmp"},
            {".c", "text/plain"},
            {".class", "application/octet-stream"},
            {".conf", "text/plain"},
            {".cpp", "text/plain"},
            {".doc", "application/msword"},
            {".docx",
                    "application/vnd.openxmlformats-officedocument.wordprocessingml.document"},
            {".xls", "application/vnd.ms-excel"},
            {".xlsx",
                    "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},
            {".exe", "application/octet-stream"},
            {".gif", "image/gif"},
            {".gtar", "application/x-gtar"},
            {".gz", "application/x-gzip"},
            {".h", "text/plain"},
            {".htm", "text/html"},
            {".html", "text/html"},
            {".jar", "application/java-archive"},
            {".java", "text/plain"},
            {".jpeg", "image/jpeg"},
            {".jpg", "image/jpeg"},
            {".js", "application/x-javascript"},
            {".log", "text/plain"},
            {".m3u", "audio/x-mpegurl"},
            {".m4a", "audio/mp4a-latm"},
            {".m4b", "audio/mp4a-latm"},
            {".m4p", "audio/mp4a-latm"},
            {".m4u", "video/vnd.mpegurl"},
            {".m4v", "video/x-m4v"},
            {".mov", "video/quicktime"},
            {".mp2", "audio/x-mpeg"},
            {".mp3", "audio/x-mpeg"},
            {".mp4", "video/mp4"},
            {".mpc", "application/vnd.mpohun.certificate"},
            {".mpe", "video/mpeg"},
            {".mpeg", "video/mpeg"},
            {".mpg", "video/mpeg"},
            {".mpg4", "video/mp4"},
            {".mpga", "audio/mpeg"},
            {".msg", "application/vnd.ms-outlook"},
            {".ogg", "audio/ogg"},
            {".pdf", "application/pdf"},
            {".png", "image/png"},
            {".pps", "application/vnd.ms-powerpoint"},
            {".ppt", "application/vnd.ms-powerpoint"},
            {".pptx",
                    "application/vnd.openxmlformats-officedocument.presentationml.presentation"},
            {".prop", "text/plain"}, {".rc", "text/plain"},
            {".rmvb", "audio/x-pn-realaudio"}, {".rtf", "application/rtf"},
            {".sh", "text/plain"}, {".tar", "application/x-tar"},
            {".tgz", "application/x-compressed"}, {".txt", "text/plain"},
            {".wav", "audio/x-wav"}, {".wma", "audio/x-ms-wma"},
            {".wmv", "audio/x-ms-wmv"},
            {".wps", "application/vnd.ms-works"}, {".xml", "text/plain"},
            {".z", "application/x-compress"},
            {".zip", "application/x-zip-compressed"}, {"", "*/*"}};
    private static Pattern emailP = Pattern.compile("\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*");//复杂匹配
    /**
     * 手机号合法性判断
     *
     * @param mobiles 要检查的手机号
     * @return
     */
    private static Pattern phoneP = Pattern
            .compile("^((13[0-9])|(14[0-9])|(15[^4,\\D])|(17[0-9])|(18[0-9]))\\d{8}$");

    /**
     * 判断网络是否连接，返回false为没有任何连接
     *
     * @param context 上下文
     * @return boolean
     */
    public static boolean isNetworkConnected(Context context) {
        if (context != null) {
            ConnectivityManager mConnectivityManager = (ConnectivityManager) context
                    .getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo mNetworkInfo = mConnectivityManager
                    .getActiveNetworkInfo();
            if (mNetworkInfo != null) {
                return mNetworkInfo.isAvailable();
            }
        }
        return false;
    }

    public static String getIP(Context context) {
        // 获取wifi服务
        WifiManager wifiManager = (WifiManager) context
                .getSystemService(Context.WIFI_SERVICE);
        // 判断wifi是否开启
        if (!wifiManager.isWifiEnabled()) {
            wifiManager.setWifiEnabled(true);
        }
        WifiInfo wifiInfo = wifiManager.getConnectionInfo();
        int ipAddress = wifiInfo.getIpAddress();
        String ip = intToIp(ipAddress);
        return ip;
    }

    private static String intToIp(int i) {

        return (i & 0xFF) + "." + ((i >> 8) & 0xFF) + "." + ((i >> 16) & 0xFF)
                + "." + (i >> 24 & 0xFF);
    }

    /**
     * 判断当前是否是WIFI网络
     *
     * @param mContext
     * @return
     */
    public static boolean isWifiNetwork(Context mContext) {
        ConnectivityManager connectivityManager = (ConnectivityManager) mContext
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetInfo = connectivityManager.getActiveNetworkInfo();
        return activeNetInfo != null
                && activeNetInfo.getType() == ConnectivityManager.TYPE_WIFI;
    }

    /**
     * 可逆的加密算法
     */
    public static String encryptmd5(String str) {
        char[] a = str.toCharArray();
        for (int i = 0; i < a.length; i++) {
            a[i] = (char) (a[i] ^ 'l');
        }

        return new String(a);
    }

    /**
     * 获取缓存目录中的自定义文件路径
     *
     * @param context  上下文
     * @param path     二级目录，三级目录中间用"/"分隔，前后不需要加"/"
     * @param fileName 文件名，自动转成md5的名字
     * @param isMD5    文件名是否加密
     * @return File
     */
    public static File getCache(Context context, String path, String fileName,
                                boolean isMD5) {
        File file = null;
        if (Environment.getExternalStorageState().equals(
                Environment.MEDIA_MOUNTED)) {
            file = new File(context.getExternalCacheDir().getPath() + "/" + path);
        } else {
            file = new File(context.getCacheDir() + "/" + path);
        }
        if (!file.exists()) {
            file.mkdirs();
        }
        if (isMD5) {
            file = new File(file.getPath() + "/" + MD5(fileName));
        } else {
            file = new File(file.getPath() + "/" + fileName);
        }
        return file;
    }

    /**
     * MD5加密，32位
     *
     * @param url 需加密的字符串
     * @return 加密后的字符串
     */
    public static String MD5(String url) {
        MessageDigest md5 = null;
        try {
            md5 = MessageDigest.getInstance("MD5");
        } catch (Exception e) {
            // e.printStackTrace();
            return getFile(url);
        }
        String string = url + SLAT; //modify for shibo.zheng 19/06/27
        char[] charArray = string.toCharArray();
        byte[] byteArray = new byte[charArray.length];
        for (int i = 0; i < charArray.length; i++) {
            byteArray[i] = (byte) charArray[i];
        }
        byte[] md5Bytes = md5.digest(byteArray);
        StringBuilder hexValue = new StringBuilder();
        for (int i = 0; i < md5Bytes.length; i++) {
            int val = ((int) md5Bytes[i]) & 0xff;
            if (val < 16) {
                hexValue.append("0");
            }
            hexValue.append(Integer.toHexString(val));
        }
        return hexValue.toString();
    }

    //add shibo.zheng 19/06/27 start

    /**
     * MD5多次加密
     * @param string  第一次加密后的字符串
     * @param times 次数
     * @return  加密后的字符串
     */
    public static String MD5(String string, int times) {
        if (TextUtils.isEmpty(string)) {
            return "";
        }
        String md5 = MD5(string);
        for (int i = 0; i < times - 1; i++) {
            md5 = MD5(md5);
        }
        return MD5(md5);
    }

    //add shibo.zheng 19/06/27 end

    /**
     * 将URL转成能够识别的目录
     */
    public static String getFile(String url) {
        String path = url;
        if (path.contains("?")) {
            path = path.replace("?", "_");
        }
        if (path.contains("/")) {
            path = path.replace("/", "_");
        }
        if (path.contains(".")) {
            path = path.replace(".", "_");
        }
        return path;
    }

    /**
     * 获取缓存目录中的自定义目录
     *
     * @param context 上下文
     * @param path    自定义目录
     * @return File
     */
    public static File getCache(Context context, String path) {
        File file = null;
        if (Environment.getExternalStorageState().equals(
                Environment.MEDIA_MOUNTED)) {
            file = new File(context.getExternalCacheDir().getPath() + "/"
                    + path);
        } else {
            file = new File(context.getCacheDir() + "/" + path);
        }
        if (!file.exists()) {
            file.mkdirs();
        }
        return file;
    }

    /**
     * 获取内部版本号
     *
     * @param context 上下文
     * @return String
     */
    public static int getVersionCode(Context context) {
        int versionCode = 0;
        try {
            PackageInfo pi = context.getPackageManager()
                    .getPackageInfo(context.getPackageName(),
                            PackageManager.GET_CONFIGURATIONS);
            versionCode = pi.versionCode;
        } catch (NameNotFoundException e) {
            // TODO Auto-generated catch block
            // e.printStackTrace();
        }
        return versionCode;
    }

    /**
     * 获取外部版本名称
     *
     * @param context 上下文
     * @return String 版本名称
     */
    public static String getVersionName(Context context) {
        String versionName = null;
        try {
            PackageInfo pi = context.getPackageManager()
                    .getPackageInfo(context.getPackageName(),
                            PackageManager.GET_CONFIGURATIONS);
            versionName = pi.versionName;
        } catch (NameNotFoundException e) {
            // TODO Auto-generated catch block
            // e.printStackTrace();
        }
        return versionName;
    }

    /**
     * 获取设备号（IMEI）
     *
     * @param context 上下文
     * @return String 设备号
     */
    public static String getDeviceId(Context context) {
        TelephonyManager tm = (TelephonyManager) context
                .getSystemService(Context.TELEPHONY_SERVICE);
        String dwc = null;
        try {
            if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
                // TODO: Consider calling
                //    ActivityCompat#requestPermissions
                // here to request the missing permissions, and then overriding
                //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                //                                          int[] grantResults)
                // to handle the case where the user grants the permission. See the documentation
                // for ActivityCompat#requestPermissions for more details.
                dwc = tm.getDeviceId();
            }

        } catch (Exception e) {
            // TODO: handle exception
            dwc = getSN(context);
        }
        return dwc;
    }

    /**
     * 获取设备序列号
     *
     * @param context 上下文
     * @return String
     */
    public static String getSN(Context context) {
        return Secure.getString(context.getContentResolver(), Secure.ANDROID_ID);
    }

    /**
     * 获取GUID
     *
     * @return String
     */
    public static String GetGUID() {
        UUID uuid = UUID.randomUUID();
        return uuid.toString();
    }

    /**
     * 转换时间格式
     *
     * @param format 传入的time的格式，例："yyyy/MM/dd HH:mm:ss"
     * @param time   时间
     * @param isTime true为返回时:分:秒，false为返回年-月-日
     * @return String
     */
    @SuppressLint("DefaultLocale")
    public static String parseTime(String format, String time, boolean isTime) {
        if (!"".equals(time)) {
            Date date = stringToDate(format, time);
            if (date == null) {
                return time;
            }
            Calendar calendar = new GregorianCalendar();
            calendar.setTime(date);
            int years = calendar.get(Calendar.YEAR);
            int month = calendar.get(Calendar.MONTH) + 1;
            int day = calendar.get(Calendar.DAY_OF_MONTH);
            int hour = calendar.get(Calendar.HOUR_OF_DAY);
            int min = calendar.get(Calendar.MINUTE);
            int ss = calendar.get(Calendar.SECOND);

            if (isTime) {
                return String.format("%02d:%02d:%02d", hour, min, ss);
            }
            return String.format("%d-%02d-%02d", years, month, day);
        }
        return time;
    }

    /**
     * String类型的时间转Date
     *
     * @param format 转换的目标格式 例如"yyyy-MM-dd HH:mm:ss"
     * @param date   要转换的时间字符串
     * @return
     */
    public static Date stringToDate(String format, String date) {
        SimpleDateFormat dateFormat = new SimpleDateFormat(format, Locale.CHINA);
        try {
            return dateFormat.parse(date);
        } catch (ParseException e) {
            // TODO Auto-generated catch block
        }
        return null;
    }

    /**
     * 转换时间格式
     *
     * @param format 传入的time的格式，例："yyyy/MM/dd HH:mm:ss"
     * @param time   时间
     * @return String 返回年-月-日 时:分
     */
    @SuppressLint("DefaultLocale")
    public static String parseTime(String format, String time) {
        if (!"".equals(time)) {
            Date date = stringToDate(format, time);
            if (date == null) {
                return time;
            }
            Calendar calendar = new GregorianCalendar();
            calendar.setTime(date);
            int years = calendar.get(Calendar.YEAR);
            int month = calendar.get(Calendar.MONTH) + 1;
            int day = calendar.get(Calendar.DAY_OF_MONTH);
            int hour = calendar.get(Calendar.HOUR_OF_DAY);
            int min = calendar.get(Calendar.MINUTE);
            int ss = calendar.get(Calendar.SECOND);

            return String.format("%d-%02d-%02d %02d:%02d", years, month, day, hour, min);
        }
        return time;
    }

    /**
     * 获取虚拟按键高度
     *
     * @param context
     * @return
     */
    public static int getNavigationBarHeight(Context context) {
        int navigationBarHeight = 0;
        Resources rs = context.getResources();
        int id = rs.getIdentifier("navigation_bar_height", "dimen", "android");
        if (id > 0 && isDeviceHasNavigationBar(context)) {
            navigationBarHeight = rs.getDimensionPixelSize(id);
        }
        return navigationBarHeight;
    }

    /**
     * 判断是否存在虚拟按键
     *
     * @param context
     * @return
     */
    public static boolean isDeviceHasNavigationBar(Context context) {
        boolean hasNavigationBar = false;
        Resources rs = context.getResources();
        int id = rs
                .getIdentifier("config_showNavigationBar", "bool", "android");
        if (id > 0) {
            hasNavigationBar = rs.getBoolean(id);
        }
        try {
            Class systemPropertiesClass = Class
                    .forName("android.os.SystemProperties");
            Method m = systemPropertiesClass.getMethod("get", String.class);
            String navBarOverride = (String) m.invoke(systemPropertiesClass,
                    "qemu.hw.mainkeys");
            if ("1".equals(navBarOverride)) {
                hasNavigationBar = false;
            } else if ("0".equals(navBarOverride)) {
                hasNavigationBar = true;
            }
        } catch (Exception e) {
            e.printStackTrace();
            hasNavigationBar = false;
        }

        return hasNavigationBar;
    }

    /**
     * 时间戳转换成时间字符窜
     *
     * @param format 时间格式
     * @param time   时间戳
     * @return
     */
    public static String date2String(String format, long time) {
        Date d = new Date(time);
        SimpleDateFormat sf = new SimpleDateFormat(format);
        return sf.format(d);
    }

    /**
     * 将时间字符串转为时间戳
     *
     * @param format 时间格式
     * @param time   时间
     * @return
     */
    public static long string2Date(String format, String time) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        Date date = new Date();
        try {
            date = sdf.parse(time);
            return date.getTime();
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            // e.printStackTrace();
            Log.e("error", "将字符串转换为时间戳异常");
            return 0;
        }
    }

    /**
     * 判断是否月份中的第一周
     *
     * @param format
     * @param date
     * @return
     */
    public static boolean dayOfWeekInMonth(String format, String date) {
        Date d = stringToDate(format, date);
        if (d == null) {
            return false;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(d);
        return calendar.get(Calendar.DAY_OF_WEEK_IN_MONTH) == Calendar.SUNDAY;
    }

    /**
     * 判断某个服务是否正在运行的方法
     *
     * @param mContext
     * @param serviceName 是包名+服务的类名（例如：net.loonggg.testbackstage.TestService）
     * @return true代表正在运行，false代表服务没有正在运行
     */
    public static boolean isServiceWork(Context mContext, String serviceName) {
        boolean isWork = false;
        ActivityManager myAM = (ActivityManager) mContext
                .getSystemService(Context.ACTIVITY_SERVICE);
        List<RunningServiceInfo> myList = myAM.getRunningServices(80);
        if (myList.size() <= 0) {
            return false;
        }
        for (int i = 0; i < myList.size(); i++) {
            String mName = myList.get(i).service.getClassName().toString();
            if (mName.equals(serviceName)) {
                isWork = true;
                break;
            }
        }
        return isWork;
    }

    /**
     * 格式化文字的颜色与大小
     *
     * @param text1  第一个字符串
     * @param text2  第二个字符串
     * @param size1  第一个字符串大小（与原尺寸的比例）
     * @param size2  第二个字符串大小（与原尺寸的比例）
     * @param color1 第一个字符串的颜色
     * @param color2 第二个字符串的颜色
     * @return
     */
    public static SpannableString formatText(String text1, String text2, float size1,
                                             float size2, int color1, int color2) {
        SpannableString spa = new SpannableString(text1 + text2);
        spa.setSpan(new RelativeSizeSpan(size1), 0, text1.length(),
                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        spa.setSpan(new RelativeSizeSpan(size2), text1.length(), text1.length()
                +
                text2.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        spa.setSpan(new ForegroundColorSpan(color1), 0, text1.length(),
                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        spa.setSpan(new ForegroundColorSpan(color2), text1.length(),
                text1.length() + text2.length(),
                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        return spa;
    }

    /**
     * 设置一串数组的颜色
     *
     * @param strs
     * @param colors
     * @return SpannableString
     */
    public static SpannableString formatText(String[] strs, int[] colors) {
        if (strs == null || colors == null) {
            return new SpannableString("");
        } else if (strs.length != strs.length)
            return new SpannableString("");

        String str = "";
        for (int i = 0; i < strs.length; i++) {
            str += strs[i];
        }
        SpannableString spa = new SpannableString(str);
        String str1 = "";
        for (int i = 0; i < colors.length; i++) {
            spa.setSpan(new ForegroundColorSpan(colors[i]), str1.length(),
                    str1.length() + strs[i].length(),
                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            str1 += strs[i];
        }
        return spa;
    }

    /**
     * 设置颜色并四舍五入
     *
     * @param context  上下文
     * @param text     需要比对的数值
     * @param dou      进行比对的数
     * @param num      小数保留位数
     * @param isJiaHao 正数前是否加＋号
     * @return
     */
    public static SpannableString formatText(Context context, double text, double dou,
                                             int num, boolean isJiaHao) {
        String str = String.format("%." + num + "f", text);
        int color;
        String n = "#.";
        for (int i = 0; i < num; i++) {
            n += "#";
        }
        double d = Parse.getInstance().parseDouble(str, n);

        if (d == 0) {
            str = "--";
            color = Color.GRAY;
        } else {
            dou = Parse.getInstance().parseDouble(dou, n);
            if (d > dou) {
                if (isJiaHao) {
                    str = "+" + str;
                }
                color = Color.RED;
            } else if (d < dou) {
                color = Color.GREEN;
            } else {
                color = Color.GRAY;
            }
        }

        SpannableString spa = new SpannableString(str);
        spa.setSpan(new ForegroundColorSpan(color), 0, str.length(),
                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        return spa;
    }

    /**
     * 设置颜色并四舍五入 针对白银，无小数点
     *
     * @param context  上下文
     * @param text     需要比对的数值
     * @param dou      进行比对的数
     * @param isJiaHao 正数前是否加＋号
     * @return
     */
    public static SpannableString formatText1(Context context, double text,
                                              double dou, boolean isJiaHao) {
        String str = String.format("%.2f", text);
        int color;
        double d = Parse.getInstance().parseDouble(str, "#.##");
        if (d == 0) {
            str = "--";
            color = Color.GRAY;
        } else {
            dou = Parse.getInstance().parseDouble(dou, "#.##");
            if (d > dou) {
                if (isJiaHao) {
                    str = "+" + str;
                }
                color = Color.RED;
            } else if (d < dou) {
                color = Color.GREEN;
            } else {
                color = Color.GRAY;
            }
        }

        str = str.substring(0, str.length() - 3);
        SpannableString spa = new SpannableString(str);
        spa.setSpan(new ForegroundColorSpan(color), 0, str.length(),
                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        return spa;
    }

    /**
     * 获取24小时格式的当前系统时间
     *
     * @param format time的格式，例："yyyy/MM/dd HH:mm:ss"
     * @param locale 时区，例：Locale.CHINA（代表中国时区）
     */
    public static String getTime24(String format, Locale locale) {
        if (format.contains("h")) {
            format = format.replace("h", "H");
        }
        SimpleDateFormat sdf = new SimpleDateFormat(format, locale);
        return sdf.format(new Date());
    }

    /**
     * 获取12小时格式的当前系统时间
     *
     * @param format time的格式，例："yyyy/MM/dd hh:mm:ss"
     * @param locale 时区，例：Locale.CHINA（代表中国时区）
     */
    public static String getTime12(String format, Locale locale) {
        if (format.contains("H")) {
            format = format.replace("H", "h");
        }
        SimpleDateFormat sdf = new SimpleDateFormat(format, locale);
        return sdf.format(new Date());
    }

    /**
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
     *
     * @param dp dp单位
     * @return px（像素）单位
     */
    public static int dp2px(float dp) {
        return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
    }

    /**
     * 根据手机的分辨率从 px(像素) 的单位 转成为 dp
     *
     * @param context 上下文
     * @param pxValue 像素单位
     * @return dp单位
     */
    public static int px2dp(Context context, float pxValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5f);
    }

    /**
     * 键盘隐藏并把焦点置为false
     *
     * @param context   上下文
     * @param editTexts EditText数组
     */
    public static void setKeyBoardFocusable(Context context, EditText... editTexts) {
        for (int i = 0; i < editTexts.length; i++) {
            editTexts[i].setFocusable(false);
            editTexts[i].setFocusableInTouchMode(false);
            InputMethodManager imm = (InputMethodManager) context
                    .getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(editTexts[i].getWindowToken(), 0);
        }
    }

    /**
     * 键盘隐藏
     *
     * @param context   上下文
     * @param editTexts EditText数组
     */
    public static void setKeyBoardGone(Context context, EditText... editTexts) {
        for (int i = 0; i < editTexts.length; i++) {
            InputMethodManager imm = (InputMethodManager) context
                    .getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(editTexts[i].getWindowToken(), 0);
        }
    }

    /**
     * 拆分比较
     *
     * @param need  需要比较的字符
     * @param alive 与之进行比较的字符
     * @param split 两个相比较的间隔符
     * @return need大于等于alive返回fals，need小于alive返回true
     */
    public static boolean isMin(String need, String alive, String split) {
        String split1 = split;
        if (split1.contains("\\")) {
            split1 = split1.replace("\\", "");
        }
        boolean bool = true;
        String[] needs;// 需要比对的数组
        String[] alives;// 进行比对数组
        if (need.contains(split1)) {
            needs = need.split(split);
        } else {
            needs = new String[1];
            needs[0] = need;
        }
        if (alive.contains(split1)) {
            alives = alive.split(split);
        } else {
            alives = new String[1];
            alives[0] = alive;
        }
        if (alives.length > needs.length) {
            for (int i = 0; i < alives.length; i++) {
                if (i < needs.length) {
                    if (Parse.getInstance().parseInt(needs[i]) >= Parse
                            .getInstance().parseInt(alives[i])) {
                        if (Parse.getInstance().parseInt(needs[i]) == Parse
                                .getInstance().parseInt(alives[i])) {
                            bool = false;
                        } else {
                            bool = false;
                            break;
                        }
                    } else {
                        bool = true;
                        break;
                    }
                } else {
                    if (Parse.getInstance().parseInt(alives[i]) <= 0) {
                        if (Parse.getInstance().parseInt(needs[i]) == 0) {
                            bool = false;
                        } else {
                            bool = false;
                            break;
                        }
                    } else {
                        bool = true;
                        break;
                    }
                }
            }
        } else {
            for (int i = 0; i < needs.length; i++) {
                if (i < alives.length) {
                    if (Parse.getInstance().parseInt(needs[i]) >= Parse
                            .getInstance().parseInt(alives[i])) {
                        if (Parse.getInstance().parseInt(needs[i]) == Parse
                                .getInstance().parseInt(alives[i])) {
                            bool = false;
                        } else {
                            bool = false;
                            break;
                        }
                    } else {
                        bool = true;
                        break;
                    }
                } else {
                    if (Parse.getInstance().parseInt(needs[i]) >= 0) {
                        if (Parse.getInstance().parseInt(needs[i]) == 0) {
                            bool = false;
                        } else {
                            bool = false;
                            break;
                        }
                    } else {
                        bool = true;
                        break;
                    }
                }
            }
        }
        return bool;
    }

    /**
     * 设置输入框焦点
     *
     * @param isFocusable 焦点布尔值
     * @param editTexts   EditText数组
     */
    public static void setFocusable(boolean isFocusable, EditText... editTexts) {
        for (int i = 0; i < editTexts.length; i++) {
            editTexts[i].setFocusable(isFocusable);
            editTexts[i].setFocusableInTouchMode(isFocusable);
        }
    }

    /**
     * 压缩图片
     *
     * @param newW 新图片宽度
     * @param newH 新图片高度
     * @param path 本地图片地址
     * @return
     */
    public static Options reduceBitmap(int newW, int newH, String path) {
        if (path == null || path.length() == 0) {
            return null;
        }
        Options op = new Options();
        op.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(path, op);
        int oldW = op.outWidth;
        int oldH = op.outHeight;
        int size = 1;// 默认不缩放
        if (oldW > oldH) {// 宽大与高的情况
            if (oldW > newW) {
                size = oldW / newW;
            }
        } else {// 高大于宽的情况
            if (oldH > newH) {
                size = oldH / newH;
            }
        }
        Options op1 = new Options();
        op1.inJustDecodeBounds = false;
        op1.inSampleSize = size;
        return op1;
    }

    /**
     * 压缩图片并返回压缩后的图片地址
     *
     * @param context 上下文
     * @param newW    新图片宽度
     * @param newH    新图片高度
     * @param path    本地图片地址
     * @return 保存成功后的地址，保存失败返回null
     */
    public static String reduceBitmap(Context context, int newW, int newH, String path) {
        if (path == null || path.length() == 0) {
            return null;
        }
        Options op = new Options();
        op.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(path, op);
        int oldW = op.outWidth;
        int oldH = op.outHeight;
        int size = 1;// 默认不缩放
        if (oldW > oldH) {// 宽大与高的情况
            if (oldW > newW) {
                size = oldW / newW;
            }
        } else {// 高大于宽的情况
            if (oldH > newH) {
                size = oldH / newH;
            }
        }
        Options op1 = new Options();
        op1.inJustDecodeBounds = false;
        op1.inSampleSize = size;

        Bitmap bm1 = BitmapFactory.decodeFile(path,
                op1);
        return saveBitmap(context, bm1);
    }

    /**
     * 保存图片到本地缓存“images_data”目录中
     *
     * @param context 上下文
     * @param bm      需要保存的Bitmap对象
     * @return 保存成功后的地址，保存失败返回null
     */
    public static String saveBitmap(Context context, Bitmap bm) {
        if (bm == null) {
            return null;
        }
        File file = null;
        if (Environment.getExternalStorageState().equals(
                Environment.MEDIA_MOUNTED)) {
            file = new File(context.getExternalCacheDir().getPath()
                    + "/images_data");
        } else {
            file = new File(context.getCacheDir().getPath() + "/images_data");
        }
        if (!file.exists()) {
            file.mkdirs();
        }
        file = new File(file.getPath() + "/"
                + String.valueOf(System.currentTimeMillis()) + ".jpeg");
        try {
            FileOutputStream fos = new FileOutputStream(file);
            bm.compress(Bitmap.CompressFormat.JPEG, 90, fos);
            fos.flush();
            fos.close();
            bm.recycle();
            bm = null;
            Options op = new Options();
            op.inSampleSize = 16;
            bm = BitmapFactory.decodeFile(file.getPath());
            if (bm == null) {
                return null;
            }
            bm.recycle();
            bm = null;
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            // e.printStackTrace();
            return null;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            // e.printStackTrace();
            return null;
        }
        return file.getPath();
    }

    /**
     * 根据文件后缀名获得对应的MIME类型。
     *
     * @param file
     */
    public static String getMIMEType(File file) {

        String type = "*/*";
        String fName = file.getName();
        // 获取后缀名前的分隔符"."在fName中的位置。
        int dotIndex = fName.lastIndexOf(".");
        if (dotIndex < 0) {
            return type;
        }
        /* 获取文件的后缀名 */
        String end = fName.substring(dotIndex, fName.length()).toLowerCase();
        if ("".equals(end)) {
            return type;
        }
        // 在MIME和文件类型的匹配表中找到对应的MIME类型。
        for (int i = 0;
             i < MIME_MapTable.length; i++) { // MIME_MapTable??在这里你一定有疑问，这个MIME_MapTable是什么？
            if (end.equals(MIME_MapTable[i][0])) {
                type = MIME_MapTable[i][1];
            }
        }
        return type;
    }

    /**
     * 顶部
     *
     * @param context 上下文
     * @param msg     提示文字
     */
    public static void showToastTop(Context context, String msg) {
        Toast toast = Toast.makeText(context, msg, Toast.LENGTH_SHORT);
        toast.setGravity(Gravity.TOP, 0, 0);
        toast.show();
    }

    /**
     * 顶部（自定义位置）
     *
     * @param context 上下文
     * @param msg     提示文字
     * @param x       横向位置
     * @param y       纵向位置
     */
    public static void showToastTop(Context context, String msg, int x, int y) {
        Toast toast = Toast.makeText(context, msg, Toast.LENGTH_SHORT);
        toast.setGravity(Gravity.TOP, x, y);
        toast.show();
    }

    /**
     * 中间
     *
     * @param context 上下文
     * @param msg     提示文字
     */
    public static void showToastCenter(Context context, String msg) {
        Toast toast = Toast.makeText(context, msg, Toast.LENGTH_SHORT);
        toast.setGravity(Gravity.CENTER, 0, 0);
        toast.show();
    }

    /**
     * 中间（自定义位置）
     *
     * @param context 上下文
     * @param msg     提示文字
     * @param x       横向位置
     * @param y       纵向位置
     */
    public static void showToastCenter(Context context, String msg, int x, int y) {
        Toast toast = Toast.makeText(context, msg, Toast.LENGTH_SHORT);
        toast.setGravity(Gravity.CENTER, x, y);
        toast.show();
    }

    /**
     * 底部
     *
     * @param context 上下文
     * @param msg     提示文字
     */
    public static void showToastBottom(Context context, String msg) {
        Toast toast = Toast.makeText(context, msg, Toast.LENGTH_SHORT);
        toast.setGravity(Gravity.BOTTOM, 0, 0);
        toast.show();
    }

    /**
     * 底部（自定义位置）
     *
     * @param context 上下文
     * @param msg     提示文字
     * @param x       横向位置
     * @param y       纵向位置
     */
    public static void showToastBottom(Context context, String msg, int x, int y) {
        Toast toast = Toast.makeText(context, msg, Toast.LENGTH_SHORT);
        toast.setGravity(Gravity.BOTTOM, x, y);
        toast.show();
    }

    public static int getScreenHeight(Context context) {
        return context.getResources().getDisplayMetrics().heightPixels;
    }

    public static int getScreenWidth(Context context) {
        return context.getResources().getDisplayMetrics().widthPixels;
    }

    /**
     * 正则表达式匹配
     *
     * @param regex 正则表达式
     * @param str   要匹配的字符串
     * @return 匹配结果
     */
    public static boolean regexMatch(String regex, String str) {
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(str);
        return matcher.matches();
    }

    /**
     * 创建流水序列号（交易模块请求时使用）
     *
     * @return 流水序列号
     */
    public static String genSeriaNo() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss",
                Locale.CHINA);
        int num = new Random().nextInt(900000) + 100000;// 生成6位随机数
        return sdf.format(new Date()) + num;
    }

    /***
     * 压缩Zip
     *
     * @param data
     * @return
     */
    public static byte[] zip(byte[] data) {
        byte[] b = null;
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ZipOutputStream zip = new ZipOutputStream(bos);
            ZipEntry entry = new ZipEntry("zip");
            entry.setSize(data.length);
            zip.putNextEntry(entry);
            zip.write(data);
            zip.closeEntry();
            zip.close();
            b = bos.toByteArray();
            bos.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return b;
    }

    /***
     * 内存数据解压
     *
     * @param data
     * @return
     */
    public static byte[] unZip(byte[] data) {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        InflaterOutputStream inflaterOutputStream = new InflaterOutputStream(byteArrayOutputStream);
        try {
            inflaterOutputStream.write(data);
            return byteArrayOutputStream.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;


//        byte[] b = null;
//        try {
//            ByteArrayInputStream bis = new ByteArrayInputStream(data);
//            ZipInputStream zip = new ZipInputStream(bis);
//            while (zip.getNextEntry() != null) {
//                byte[] buf = new byte[1024];
//                int num = -1;
//                ByteArrayOutputStream baos = new ByteArrayOutputStream();
//                while ((num = zip.read(buf, 0, buf.length)) != -1) {
//                    baos.write(buf, 0, num);
//                }
//                b = baos.toByteArray();
//                baos.flush();
//                baos.close();
//            }
//            zip.close();
//            bis.close();
//        } catch (Exception ex) {
//            ex.printStackTrace();
//        }
//        return b;
    }

    public static boolean isMobileNO(String mobiles) {

        Matcher m = phoneP.matcher(mobiles);

        return m.matches();
    }

    public static boolean isEmail(String email) {
        if (TextUtils.isEmpty(email)) {
            return false;
        }
        Matcher m = emailP.matcher(email);
        return m.matches();
    }

    public static int getDisplayWidth(Context context) {
        return context.getResources().getDisplayMetrics().widthPixels;
    }

    public static int getDisplayHeight(Context context) {
        return context.getResources().getDisplayMetrics().heightPixels;
    }

    /**
     * 根据类名创建类实例
     *
     * @param className
     * @param <T>
     * @return
     * @throws Exception
     */
    public static <T> T createClassInstanceByName(String className) throws Exception {
        Class c;
        T o;

        c = Class.forName(className);
        o = (T) (c.newInstance());

        return o;
    }

    public static void dispose(Disposable disposable) {
        if (disposable != null && !disposable.isDisposed()) {
            disposable.dispose();
        }

    }

    public static void bindViewPagerAndTabLayout(FragmentManager supportFragmentManager, List<Fragment> fragments, String[] titles, ViewPager viewPager, TabLayout tabLayout) {
        TabLayoutFragmentPagerAdapter pagerAdapter = new TabLayoutFragmentPagerAdapter(supportFragmentManager, fragments, titles);
        assert viewPager != null;
        viewPager.setAdapter(pagerAdapter);
        assert tabLayout != null;
        tabLayout.setupWithViewPager(viewPager);
    }

    public static String getMinImage(String url) {
        if (!TextUtils.isEmpty(url)) {
            String tempUrl = url;
            if (!url.startsWith("http")) {
                tempUrl = KBaseApplication.IP + url;
            }
            String startUrl = tempUrl.substring(0, tempUrl.lastIndexOf("."));
            String endUrl = tempUrl.substring(tempUrl.lastIndexOf("."));
            return startUrl + "_min" + endUrl;
        } else {
            return "";
        }
    }

    @NonNull
    public static FlexboxLayoutManager getFlexBoxLayoutManager(Context context) {
        FlexboxLayoutManager layoutManager = new FlexboxLayoutManager(context);
        layoutManager.setFlexDirection(FlexDirection.ROW);
        layoutManager.setAlignItems(AlignItems.STRETCH);
        layoutManager.setJustifyContent(JustifyContent.FLEX_START);
        layoutManager.setFlexWrap(FlexWrap.WRAP);
        return layoutManager;
    }

    /**
     * 判断市场是否存在
     *
     * @param context
     * @param pkgName
     * @return
     */
    public static boolean isAvilible(Context context, String pkgName) {
        final PackageManager packageManager = context.getPackageManager();
        List<PackageInfo> packageInfos = packageManager.getInstalledPackages(0);
        List<String> nameList = new ArrayList<>();
        if (packageInfos != null) {
            for (int i = 0; i < packageInfos.size(); i++) {
                String pn = packageInfos.get(i).packageName;
                nameList.add(pn);
            }
        }

        return nameList.contains(pkgName);
    }

    /**
     * 跳转到APP详情界面
     *
     * @param appPkg    APP的包名
     * @param marketPkg 应用商店包名
     */
    public static void launchAppDetail(Context context, String appPkg, String marketPkg) {
        try {
            if (TextUtils.isEmpty(appPkg)) {
                return;
            }

            Uri uri = Uri.parse("market://details?id=" + appPkg);
            Intent intent = new Intent(Intent.ACTION_VIEW, uri);
            if (!TextUtils.isEmpty(marketPkg)) {
                intent.setPackage(marketPkg);
            }
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void setSystemUi(Window window, boolean lightStatusBar) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            View decor = window.getDecorView();
            int ui = decor.getSystemUiVisibility();
            if (lightStatusBar) {
                ui |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
            } else {
                ui &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
            }
            decor.setSystemUiVisibility(ui);
        }
    }

    public static void setStatusBarColor(Activity activity, int color) {
        Window window = activity.getWindow();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
//            window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.setStatusBarColor(color);
            return;
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }
    }

    private boolean isGpsEnable(Context mContext) {
        LocationManager locationManager = ((LocationManager) mContext
                .getSystemService(Context.LOCATION_SERVICE));
        return Objects.requireNonNull(locationManager).isProviderEnabled(LocationManager.GPS_PROVIDER);
    }


    public static BigDecimal getActivityPrice(BigDecimal nowPrice, BigDecimal payCake) {
        return nowPrice.subtract(nowPrice.multiply(payCake));
    }

    public static BigDecimal getActivityTegral(BigDecimal nowPrice, BigDecimal payCake) {
        return nowPrice.multiply(payCake);
    }

    //add shibo.zheng 19/06/24 start
    /**
     * 动态设置缩进距离的方式
     * @param tag
     * @param title
     * @param text
     */
    public static void calculateTag(TextView tag, TextView title, final String text) {
        ViewTreeObserver observer = tag.getViewTreeObserver();
        observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            @Override
            public boolean onPreDraw() {
                SpannableString spannableString = new SpannableString(text);
                //这里没有获取margin的值，而是直接写死的
                //用前面的label标签的宽度+5dp等于缩进的宽度
                LeadingMarginSpan.Standard what = new LeadingMarginSpan.Standard(tag.getWidth() + dp2px(5), 0);
                spannableString.setSpan(what, 0, spannableString.length(), SpannableString.SPAN_INCLUSIVE_INCLUSIVE);
                title.setText(spannableString);
                tag.getViewTreeObserver().removeOnPreDrawListener(
                        this);
                return false;
            }
        });
    }
    //add shibo.zheng 19/06/24 end
}
